package debtbundler.domain.entity;

import java.util.Set;

/**
 * An abstract "pool" of money to and from which money can be transferred.
 * <p>
 * Although a method to remove any <code>Transaction</code> from a pool
 * is declared here, it is left for extensions of this class to declare 
 * what specific types of <code>Transaction</code>s they allow to be added.
 * 
 * @see Transaction
 * @author Anssi
 *
 */
public interface MoneyPool extends Entity {
	
	/**
	 * @return	the name of this pool
	 */
	public String getName();
	
	/**
	 * Returns the transactions that bring in money
	 * to this pool.
	 *  
	 * @return	the input transactions to this pool
	 */
	public Set<Transaction> getInputTransactions();	

	/**
	 * Returns the transactions that withdraw money
	 * from this pool.
	 *  
	 * @return	the output transactions from this pool
	 */
	public Set<Transaction> getOutputTransactions();	
	
	/**
	 * Returns all transactions from or to this pool.
	 *  
	 * @return	all transactions from or to this pool
	 */
	public Set<Transaction> getTransactions();	
	
	/**
	 * Removes a transaction from this pool.
	 * <p> 
	 * For data consistency, implementations of this interface must make 
	 * sure that the transaction is removed from both the "from" and "to"
	 * pools regardless of which end it is first removed.
	 * 
	 * @param transaction	transaction to remove
	 * @return				<code>true</code> if the transaction was removed
	 */
	public boolean removeTransaction(Transaction transaction);
	

	/**
	 * Returns the balance of transactions to and from this pool. 
	 * Input transactions are valued as positive, output transactions
	 * as negative.
	 * 
	 * @return	the balance of this pool
	 */
	public double getBalance();	
	
	/**
	 * Tells if this pool is balanced with respect to values of its input 
	 * and output flows. It is balanced if <code>getBalance()</code> is zero
	 * within accuracy of 0.005. 
	 * 
	 * @return	<code>true</code> if this pool is balanced
	 * @see getBalance()
	 */
	public boolean isBalanced();	

}
